import type { ProColumns } from '@/components/Pro';
import { ProTable } from '@/components/Pro';
import {
  statisticElectricityControllerGetDayReport,
  statisticElectricityControllerGetMonthReport,
  statisticElectricityControllerGetYearReport,
} from '@/services/ess/statisticElectricity';
import { useIntl } from '@umijs/max';
import dayjs from 'dayjs';
import moment from 'moment';
import React, { useEffect, useRef, useState } from 'react';

import { parseArray } from '@/pages/Statistics/Battery/utils';
import { dateFormatterMap, rowToColumns, selectTypeMap } from '@/pages/Statistics/Electric/helper';
import { TreeNode } from '@/pages/Statistics/ElectricityConsumption/help';
import _ from 'lodash';
import './Common.less';

type areaColumnsType = {
  title: string;
  dataIndex: string;
  key: string;
  hideInSearch: boolean;
};
type IProps = {
  dateType: string;
  deviceInfos: any;
  changeReportData: (data: { codes: string[]; date: string }) => void;
};
const requestMap = {
  day: statisticElectricityControllerGetDayReport,
  month: statisticElectricityControllerGetMonthReport,
  year: statisticElectricityControllerGetYearReport,
};
const dataSumMap = {
  day: 'statistics.common.daySum',
  date: 'statistics.common.daySum',
  month: 'statistics.common.monthSum',
  year: 'statistics.common.yearSum',
};
const ElectricReport: React.FC<IProps> = (props) => {
  const intl = useIntl();
  const tableColumnsMap = new Map<string, string>([
    ['chargeCapacity', `${intl.formatMessage({ id: 'statistics.common.charge' })}(kWh)`],
    ['dischargeCapacity', `${intl.formatMessage({ id: 'statistics.common.discharge' })}(kWh)`],
    ['chargeTimes', `${intl.formatMessage({ id: 'statistics.work.chargeTimes' })}`],
    ['dischargeTimes', `${intl.formatMessage({ id: 'statistics.work.dischargeTimes' })}`],
  ]);
  const [deviceValue, setDeviceValue] = useState();

  const actionRef = useRef(null);
  const [isEmpty, changeIsEmpty] = useState(false);
  const { deviceInfos, changeReportData, dateType } = props;
  const deviceTree = useRef(deviceInfos?.treeData);
  const [dateVal, setDateVal] = useState<string>(dayjs().format(dateFormatterMap.get(dateType)));
  const [deviceVal, setDeviceVal] = useState<string>();
  const [areaFlag, setAreaFlag] = useState(false);
  const [stationFlag, setStationFlag] = useState(true);
  // code input value , 支持多选后的请求参数中的 code
  const [totalData, setTotalData] = useState({}) as any;
  console.log('totalData', totalData);
  const [summary, setSummary] = useState<API.StatisticInfo[]>([]);
  const [columnsState, setColumnsState] = useState({});
  const selectedType = useRef(null);
  /**
   * 获得对应的columns
   * @param keys
   */
  const getAreaColumns = (keys: string[]): areaColumnsType[] => {
    return keys.map((item: string) => {
      const nameArr = item.split('_');
      return {
        title: `${nameArr[0]}_${tableColumnsMap.get(nameArr[1])}`,
        dataIndex: item,
        key: item,
        hideInSearch: true,
      };
    });
  };
  /**
   * 获得禁用列表
   * @param Nodes
   */
  const setDisabled = (Nodes: TreeNode[]): TreeNode[] => {
    return Nodes.map((node) => {
      const newNode: TreeNode = {
        ...node,
        disabled: selectedType.current === null ? false : node.nodeType !== selectedType.current,
      };
      if (newNode.subDevices) {
        newNode.subDevices = setDisabled(newNode.subDevices);
      }
      return newNode;
    });
  };
  const baseColumns: ProColumns[] = [
    {
      title: intl.formatMessage({ id: 'statistics.income.select' }),
      dataIndex: 'date',
      initialValue: new Date(),
      key: 'date',
      valueType: selectTypeMap.get(dateType),
      hideInTable: true,
      fieldProps: {
        allowClear: false,
        disabledDate: (current: any) => {
          if (dateType === 'day') {
            return current && current > moment().endOf('day');
          } else if (dateType === 'month') {
            return current && current > moment().endOf('month');
          } else {
            return current && current > moment().endOf('year');
          }
        },
        onChange: (e: Date, value: string) => {
          setDateVal(value);
        },
      },
    },
    {
      title: intl.formatMessage({ id: 'statistics.work.dimensions' }),
      dataIndex: 'codes',
      key: 'codes',
      valueType: 'treeSelect',
      fieldProps: {
        maxCount: 100,
        maxTagCount: 'responsive',
        multiple: true,
        value: deviceVal,
        showSearch: true,
        treeData: deviceTree?.current,
        fieldNames: {
          label: 'deviceName',
          value: 'uniqueId',
          children: 'subDevices',
        },
        onSelect: function (...args) {
          let selectOptions = args[1];
          if (selectedType.current === null && selectOptions?.nodeType) {
            selectedType.current = selectOptions?.nodeType;
          }
          // setDeviceTree(setDisabled([deviceTree[0]]));
          deviceTree.current = setDisabled([deviceTree?.current[0]]);
        },
        onChange: (...args) => {
          setDeviceVal(args[0]);
          let selectedOptions = args[1];
          if (!selectedOptions.length) {
            //清除后不再做相应限制
            selectedType.current = null;
            // setDeviceTree(setDisabled([deviceTree[0]]));
            deviceTree.current = setDisabled([deviceTree?.current[0]]);
          }
          let hasAreaNode: boolean = false;
          let hasStationNode: boolean = false;
          const ans = parseArray(args[0]);
          if (ans.nodeType.length) {
            hasAreaNode = ans.nodeType.some((item: string) => {
              return item === 'AREA';
            });
          }
          if (ans.nodeType.length) {
            hasStationNode = ans.nodeType.some((item: string) => {
              return item === 'ROOT';
            });
          }
          setAreaFlag(hasAreaNode);
          setStationFlag(hasStationNode);
          setDeviceValue(ans.id.length > 1 ? ans.id.join(',') : ans.id[0]);
        },
      },
      hideInTable: true,
    },
    {
      title: intl.formatMessage({ id: 'batteryVoltage.no' }),
      valueType: 'index',
      dataIndex: 'pageIndex',
      hideInSearch: true,
      width: 90,
    },
    {
      title: intl.formatMessage({ id: 'global.date' }),
      dataIndex: 'date',
      hideInSearch: true,
      width: 100,
    },
    {
      title: intl.formatMessage({ id: 'statistics.common.period' }),
      dataIndex: 'startTime',
      hideInTable: dateType !== 'day',
      hideInSearch: true,
      render: (_, record) => (
        <span>
          {record.startTime}-{record.endTime}
        </span>
      ),
      width: 156,
    },
  ];
  const stationColumns = [
    {
      title: `${intl.formatMessage({ id: 'statistics.common.charge' })}(kWh)`,
      dataIndex: 'chargeCapacity',
      hideInSearch: true,
    },
    {
      title: `${intl.formatMessage({ id: 'statistics.common.discharge' })}(kWh)`,
      dataIndex: 'dischargeCapacity',
      hideInSearch: true,
    },
    {
      title: intl.formatMessage({ id: 'statistics.work.chargeTimes' }),
      dataIndex: 'chargeTimes',
      hideInSearch: true,
    },
    {
      title: intl.formatMessage({ id: 'statistics.work.dischargeTimes' }),
      dataIndex: 'dischargeTimes',
      hideInSearch: true,
    },
  ];
  useEffect(() => {
    if (deviceInfos?.treeData?.length > 0) {
      setDeviceValue(deviceInfos.treeData[0].stationCode);
      setDeviceVal(deviceInfos.treeData[0].uniqueId);
      actionRef?.current.reload();
    }
  }, [deviceInfos.treeData]);
  const [dynamicColumns, setDynamicColumns] = useState<ProColumns[]>(baseColumns);
  const [elseColumns, setElseColumns] = useState(stationColumns);

  useEffect(() => {
    changeReportData({
      date: dateVal,
      codes: deviceValue,
      areaFlag: areaFlag,
    });
    setDynamicColumns([...baseColumns, ...elseColumns]);
  }, [dateVal, deviceValue]);
  useEffect(() => {
    if (deviceInfos?.treeData?.length > 0) {
      selectedType.current = 'ROOT';
      deviceTree.current = setDisabled([deviceInfos?.treeData[0]]);
    }
  }, []);
  const renderSummary = () => {
    return (
      <ProTable.Summary.Row>
        {columnsState['pageIndex']?.show !== false && (
          <ProTable.Summary.Cell index={0}>
            {intl.formatMessage({ id: dataSumMap[dateType] })}
          </ProTable.Summary.Cell>
        )}
        {columnsState['date']?.show !== false && (
          <ProTable.Summary.Cell index={1}></ProTable.Summary.Cell>
        )}
        {columnsState['startTime']?.show !== false && dateType === 'day' && (
          <ProTable.Summary.Cell index={2}></ProTable.Summary.Cell>
        )}
        {summary
          .flatMap((item, summaryIndex) => [
            { key: `chargeCapacity${summaryIndex + 1}`, value: item.chargeCapacity },
            { key: `dischargeCapacity${summaryIndex + 1}`, value: item.dischargeCapacity },
            { key: `chargeTimes${summaryIndex + 1}`, value: item.chargeTimes },
            { key: `dischargeTimes${summaryIndex + 1}`, value: item.dischargeTimes },
          ])
          .map(
            (item, index) =>
              columnsState[item.key]?.show !== false && (
                <ProTable.Summary.Cell key={index} index={index + 3}>
                  {item.value}
                </ProTable.Summary.Cell>
              ),
          )}
      </ProTable.Summary.Row>
    );
  };
  return (
    <>
      <ProTable
        headerTitle=""
        rowKey={'reportId'}
        columns={dynamicColumns}
        onReset={() => {
          setDeviceValue(deviceInfos.treeData[0].stationCode);
          setDeviceVal([deviceInfos.treeData[0].uniqueId]);
          selectedType.current = 'ROOT';
          deviceTree.current = setDisabled([deviceTree?.current[0]]);
          setAreaFlag(false);
          setStationFlag(true);
          setDateVal(dayjs().format(dateFormatterMap.get(dateType)));
          changeReportData({
            date: dayjs().format(dateFormatterMap.get(dateType)),
            deviceCode: deviceInfos.treeData[0].stationId,
            areaFlag: false,
          });
        }}
        actionRef={actionRef}
        scroll={{ x: 'max-content' }}
        request={async (values) => {
          const params = {
            ...values,
            codes: deviceValue,
            date: dayjs(values.date).format(dateFormatterMap.get(dateType)),
            areaFlag: areaFlag,
          };
          const newParams: typeof params = {
            ...params,
            pageSize: !stationFlag ? 20 * (params?.codes.split(',')?.length || 1) : 20,
          };
          const res = await requestMap[dateType](newParams);
          const forRes = rowToColumns(res.data.page.records, dateType === 'day');
          const keys = _.slice(Object.keys(forRes[0]), 6);
          setTotalData(res.data.total);
          if (!stationFlag) {
            setDynamicColumns([...baseColumns, ...getAreaColumns(keys)]);
            setElseColumns(getAreaColumns(keys));
          } else {
            setDynamicColumns([...baseColumns, ...stationColumns]);
            setElseColumns(stationColumns);
          }
          changeIsEmpty(Number(res.data?.page?.total || 0) === 0);
          setSummary(res.data.total);
          return {
            data: !stationFlag ? forRes : res.data.page.records,
            success: res.success,
            total: !stationFlag
              ? Number(res.data.page.total) / res.data.total.length
              : res.data.page.total,
          };
        }}
        columnsState={{
          value: columnsState,
          onChange: setColumnsState,
        }}
        summary={() => !isEmpty && renderSummary()}
        search={{
          className: 'searchPosInline',
        }}
        toolbar={{
          className: 'toobalrZindex',
          actions: [
            // eslint-disable-next-line react/button-has-type
          ],
        }}
      ></ProTable>
    </>
  );
};

export default ElectricReport;
